package cn.mengfly.testnrz.curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import java.io.Closeable;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author Mengfly
 */
public class ZkClient implements Closeable {
    private static final String ZK_ADDRESS = "127.0.0.1:2181";

    private final CuratorFramework client;

    private ZkClient() {
        client = ClientFactory.createSimple(ZK_ADDRESS);
    }

    public boolean delete(String lockedPath) {
        if (isNodeExists(lockedPath)) {
            try {
                client.delete().forPath(lockedPath);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    void init() {
        client.start();
    }


    @Override
    public void close() {
        client.close();
    }

    public boolean isNodeExists(String zkPath) {
        try {
            Stat stat = client.checkExists().forPath(zkPath);
            return null != stat;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public void createNode(String zkPath, String data) {
        try {
            byte[] payload = "to set content".getBytes(StandardCharsets.UTF_8);
            if (data != null) {
                payload = data.getBytes(StandardCharsets.UTF_8);
            }
            client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(zkPath, payload);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String createEphemeralSeqNode(String zkPath) {
        try {
            byte[] payload = "to set content".getBytes(StandardCharsets.UTF_8);
            return client.create().creatingParentsIfNeeded()
                    .withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(zkPath, payload);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void deleteNode(String zkPath) {
        try {
            client.delete().forPath(zkPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public CuratorFramework getClient() {
        return client;
    }

    private static ZkClient instance = null;

    public static ZkClient inst() {
        if (instance == null) {
            synchronized (ZkClient.class) {
                if (instance == null) {
                    instance = new ZkClient();
                    instance.init();
                }
            }
        }
        return instance;
    }


    public List<String> getChildren(String zkPath) {
        try {
            return client.getChildren().forPath(zkPath);
        } catch (Exception e) {
            return null;
        }
    }
}
